package com.yzc.util;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Slf4j
@Component
@RequiredArgsConstructor
public class RabbitMQUtil {

    private final RabbitTemplate rabbitTemplate;

    /**
     * 发送阶梯式延迟消息
     *
     * @param exchange   交换机名称
     * @param routingKey 路由键
     * @param message    消息内容
     * @param delays     阶梯式延迟时间（单位：毫秒）
     */
    public void sendStaggeredDelayedMessages(String exchange, String routingKey, Object message, int[] delays) {
        for (int delay : delays) {
            rabbitTemplate.convertAndSend(
                    exchange,
                    routingKey,
                    message,
                    msg -> {
                        // 设置延迟时间
                        msg.getMessageProperties().setDelay(delay);
                        return msg;
                    }
            );
            log.info(" [x] 将延迟消息发送到交换 {}, 路由键: {}, 延迟: {} ms", exchange, routingKey, delay);
        }
    }

    /**
     * 动态生成阶梯式延迟时间
     *
     * @return 阶梯式延迟时间数组
     */
    public int[] generateDelays() {
        // 定义阶梯式延迟时间的初始部分
        int[] initialDelays = {30000, 60000, 120000,120000,120000};

        // 计算初始部分的总延迟时间
        int totalInitialDelay = Arrays.stream(initialDelays).sum();

        // 计算剩余时间（30 分钟 - 初始部分的总延迟时间）
        int remainingDelay = 30 * 60 * 1000 - totalInitialDelay; // 30 分钟，单位：毫秒

        // 如果剩余时间大于 0，则补充到最后一条消息中
        if (remainingDelay > 0) {
            int[] delays = Arrays.copyOf(initialDelays, initialDelays.length + 1);
            delays[delays.length - 1] = remainingDelay;
            return delays;
        }

        // 如果剩余时间小于等于 0，则直接返回初始部分
        return initialDelays;
    }

    public void cancelDelayedMessage(String exchange, String routingKey, Long orderId) {
        // 发送一条取消消息到相同的队列
        rabbitTemplate.convertAndSend(
                exchange,
                routingKey,
                "CANCEL:" + orderId,
                msg -> {
                    // 设置消息的唯一 ID
                    msg.getMessageProperties().setMessageId("CANCEL:" + orderId);
                    // 设置延迟时间为 0（立即发送）
                    msg.getMessageProperties().setDelay(0);
                    return msg;
                }
        );
        log.info(" [x] 发送取消消息到交换 {}, 路由键: {}, 订单ID: {}", exchange, routingKey, orderId);
    }
}